package au.com.langdale.gwt.client.remote;


import java.util.ArrayList;

import au.com.langdale.gwt.client.binding.BindingManager;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowCloseListener;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * EditManager extends BindingManager with the notion of a selection and 
 * a set of editing commands and properties useful to a user interface.
 * It also handles the window close event to prevent accidental loss
 * of edits.<p>
 * 
 * Subclasses must implement the cutout method, push(), to complete the save()
 * operation. Push() should arrange to call back the EditManager via its 
 * AsyncCallback interface on completion.<p>
 * 
 * See the instructions in BindingManager.<p>  
 * 
 * @author adv
 *
 */
abstract public class EditManager extends BindingManager implements WindowCloseListener, AsyncCallback {
	public EditManager() {
		Window.addWindowCloseListener(this);
	}
	
	public void save() {
		if( hasUpdates())
			push(getUpdates(), getDeleted());
	}
	
	abstract protected void push(ArrayList updates, ArrayList deleted);

	private Object selected = null;
	
	public Object getSelected() {
		return selected;
	}
	
	public void setSelected(Object model) {
		if( selected != null)
			clearSelection();
		selected = model;
		fireChange(model);
	}
	
	public void clearSelection() {
		Object model = selected;
		selected = null;
		fireChange(model);
	}
	
	public void delete() {
		Object model = getSelected();
		if( model != null)
			markDeleted(model);
	}
	
	public boolean canDelete() {
		Object model = getSelected();
		return model != null && ! isDeleted(model);
	}

	public void onFailure(Throwable caught) {
		Window.alert("Changes were not saved: " + caught);
	}

	public void onSuccess(Object result) {
		clearUpdates();
		clients.fireCommit(this);
	}

	public String onWindowClosing() {
		if( hasUpdates() )
			return "There are unsaved changes.";
		else
			return null;
	}

	public void onWindowClosed() {
		
	}
}